define(function (require, exports, module) {
    require('./css/style.css')
    const streetStyle = require('../../../map/mapbox/style/street.js').onload();
    const imageStyle = require('../../../map/mapbox/style/image.js').onload();
    const drawStyle = require('../../../map/mapbox/style/draw.js').onload();
    const Compare = require('../../../map/mapbox/compare/compare.js').onload();

    const {DirectSelect} = require('../../../map/mapbox/modes/DirectSelect.js').onload();
    const {SimpleSelect} = require('../../../map/mapbox/modes/SimpleSelect.js').onload();
    const {DrawBuilding} = require('./modes/DrawBuilding.js').onload();
    const {PolygonStickToEvents} = require('../../../map/mapbox/modes/PolygonStickTo.js').onload();

    const api = require('./config.json')

    function onload() {
        // 兄弟图层和数据源共用ID
        const brothersId = "building-brothers"
        const brothersCenterId = "building-brothers-center"
        // 父网格图层和数据源共用ID
        const parentId = "building-parent"
        // 所属地址点位
        const siteCenterId = "building-site-center"

        return {
            name: 'MapboxContainer',
            template: require('./Widget.html'),
            props: {
                // 数据ID
                dataId: {
                    type: Number,
                    default: 0,
                    required: false
                },
                // 基础地址ID
                addressId: {
                    type: Number,
                    default: 1,
                    required: false
                },
                mapId: {
                    type: String,
                    default: 'mapboxContainer',
                    required: false
                },
                width: {
                    type: String,
                    default: '100%',
                    required: false
                },
                height: {
                    type: String,
                    default: '770px',
                    required: false
                },
                // 数据类型: 1: 点, 2: 线, 3: 面
                type: {
                    type: Number,
                    default: 1,
                    required: false
                },
                // 坐标数组, 点为一维数组, 线为二维数组, 面为三维度数组
                coordinates: {
                    type: Array,
                    required: true
                }
            },
            data() {
                return {
                    minZoom: 9,
                    maxZoom: 9,
                    // A图
                    mapA: undefined,
                    // B图
                    mapB: undefined,
                    // A绘制控件
                    drawA: undefined,
                    // B绘制控件
                    drawB: undefined,
                    parent: {},
                    brothers: {},
                    noParent: false,
                    currentCoordinates: this.coordinates,
                    // 是否初始加载
                    firstLoad: true
                }
            },
            watch: {
                coordinates: {
                    handler(val) {
                        if (val && val.length > 0) {
                            this.show(this.mapA, this.drawA, val)
                            this.show(this.mapB, this.drawB, val)
                            this.drawA.changeMode('simple_select')
                            this.drawB.changeMode('simple_select')
                        } else {
                            this.drawA.deleteAll()
                            this.drawB.deleteAll()
                            this.drawA.changeMode('draw_building', {parent: this.parent, brothers: this.brothers})
                            this.drawB.changeMode('draw_building', {parent: this.parent, brothers: this.brothers})
                        }
                    },
                    deep: true
                },
                currentCoordinates: {
                    handler(val) {
                        this.$emit('update:coordinates', val)
                    },
                    deep: true
                }
            },
            mounted() {
                this.init()
            },
            created() {
                const mapConfig = window.config.map
                this.minZoom = mapConfig.minZoom
                this.maxZoom = mapConfig.maxZoom
            },
            methods: {
                preDraw() {
                    if (this.noParent) {
                        this.$message.error("请先绘制父网格！");
                    } else {
                        this.drawA.changeMode('draw_building', {parent: this.parent, brothers: this.brothers})
                        this.drawB.changeMode('draw_building', {parent: this.parent, brothers: this.brothers})
                    }
                },
                handleSelect(item) {
                    this.mapA.flyTo({
                        center: [item.x, item.y],
                        zoom: 16
                    })
                    this.mapB.flyTo({
                        center: [item.x, item.y],
                        zoom: 16
                    })
                },
                show(map, draw, coordinates) {
                    if(this.firstLoad) {
                        const bbox = turf.bbox(turf.polygon(coordinates))
                        map.fitBounds([
                            [bbox[0], bbox[1]],
                            [bbox[2], bbox[3]]
                        ], {
                            animate: false,
                            padding: {
                                top: 0,
                                bottom: 0,
                                left: 50,
                                right: 50
                            }
                        })
                    }
                    draw.deleteAll()
                    draw.add({
                        type: 'Feature',
                        properties: {},
                        geometry: {
                            type: 'Polygon',
                            coordinates: coordinates
                        }
                    })
                },
                /**
                 * 同步地图绘制
                 * @param mapA  地图A
                 * @param drawB 绘制B
                 */
                syncDraw(mapA, drawB) {

                    mapA.on(PolygonStickToEvents.CREATE, (e) => {
                        const feature = e.features[0];
                        this.currentCoordinates = feature.geometry.coordinates
                        drawB.deleteAll()
                        drawB.add(feature)
                        drawB.changeMode('simple_select', {featureIds: [feature.id]})
                    })
                    mapA.on(PolygonStickToEvents.UPDATE, (e) => {
                        const feature = e.features[0];
                        this.currentCoordinates = feature.geometry.coordinates
                        drawB.deleteAll()
                        drawB.add(feature)
                        drawB.changeMode('simple_select', {featureIds: [feature.id]})
                    })
                },
                init() {
                    const before = this.addMap('before', streetStyle)
                    // const before = addMap('before', 'mapbox://styles/mapbox/streets-v11')
                    this.mapA = before.map
                    this.drawA = before.draw
                    const after = this.addMap('after', imageStyle)
                    // const after = this.addMap('after', 'mapbox://styles/mapbox/satellite-streets-v11')
                    this.mapB = after.map
                    this.drawB = after.draw

                    this.mapA.on(PolygonStickToEvents.UPDATE_POINT_B, ({coordinatesArr}) => {
                        this.show(this.mapB, this.drawB, coordinatesArr)
                    })

                    this.mapB.on(PolygonStickToEvents.UPDATE_POINT_A, ({coordinatesArr}) => {
                        this.show(this.mapA, this.drawA, coordinatesArr)
                    })

                    this.syncDraw(this.mapA, this.drawB)
                    this.syncDraw(this.mapB, this.drawA)
                    new Compare(this.mapA, this.mapB, '#comparison-container', {});

                    if (this.currentCoordinates && this.currentCoordinates.length > 0) {
                        this.show(this.mapA, this.drawA, this.currentCoordinates)
                        this.show(this.mapB, this.drawB, this.currentCoordinates)
                        this.drawA.changeMode('simple_select')
                        this.drawB.changeMode('simple_select')
                    }

                    setTimeout(() => {
                        this.firstLoad = false
                    }, 3000)
                },
                addMap(container, style) {
                    const mapConfig = window.config.map
                    const hasCoordinates = this.currentCoordinates && this.currentCoordinates[0] &&
                        this.currentCoordinates[0].length > 0
                    const mapCenter = hasCoordinates ? this.currentCoordinates[0][0] : [mapConfig.center[0],
                        mapConfig.center[1]]

                    const map = new mapboxgl.Map({
                        accessToken: "pk.eyJ1IjoicGF1bGFuZGNvZGUiLCJhIjoiY2txdm94bmtmMGdsaDJvcGFia2N4M2ZydiJ9.wc0YPacoNAtaTrNCoZd8Fg",
                        container: container,
                        style: style,
                        center: mapCenter,
                        minZoom: this.minZoom,
                        maxZoom: this.maxZoom,
                        zoom: 12
                    })
                    map.doubleClickZoom.disable();
                    // 指南针控件
                    map.addControl(new mapboxGlControls.CompassControl(), 'bottom-right')
                    // 语言控件
                    map.addControl(new mapboxGlControls.LanguageControl({language: 'zh'}))
                    // 绘图控件
                    const draw = new MapboxDraw({
                        displayControlsDefault: false,
                        styles: drawStyle,
                        modes: Object.assign(MapboxDraw.modes, {
                            draw_building: DrawBuilding,
                            simple_select: SimpleSelect,
                            direct_select: DirectSelect
                        })
                    })
                    map.addControl(draw)
                    map.on('load', () => {
                        this.initLayer(map)
                    })
                    return {
                        map,
                        draw
                    }
                },
                // 初始化图层
                initLayer(map) {
                    const colors = map.getStyle().name === "Mapbox Streets" ? {
                        brothers: 'rgb(15,50,227)',
                        parent: '#000'
                    } : {
                        brothers: 'rgb(83,238,224)',
                        parent: '#fff'
                    }

                    this.addEmptySource(map, brothersId)
                    this.addEmptySource(map, parentId)
                    this.addEmptySource(map, brothersCenterId)
                    this.addEmptySource(map, siteCenterId)

                    this.addLineLayer(map, parentId, parentId, colors.parent)
                    this.addLineLayer(map, brothersId, brothersId, colors.brothers)
                    this.addTextLayer(map, brothersCenterId, brothersCenterId, colors.brothers)
                    this.addPointLayer(map, siteCenterId, 20, '#16a085', false)

                    this.initData(map)
                },
                // 初始化数据
                initData(map) {
                    $.get(alluse.bigcenter + api.查询全部 + this.addressId + "/" + this.dataId, res => {
                        if (res.code === 200) {
                            this.noParent = false
                            const data = res.data
                            this.parent = data.parent
                            this.brothers = data.brothers
                            map.getSource(parentId).setData(data.parent)
                            map.getSource(brothersId).setData(data.brothers)
                            map.getSource(brothersCenterId).setData(data.brothersCenter)
                            map.getSource(siteCenterId).setData(data.siteCenter)

                            if (this.currentCoordinates.length === 0) {
                                const parent = turf.multiPolygon(data.parent.geometry.coordinates)
                                const bbox = turf.bbox(parent)
                                map.fitBounds([
                                    [bbox[0], bbox[1]],
                                    [bbox[2], bbox[3]]
                                ], {
                                    animate: false,
                                    padding: {
                                        top: 0,
                                        bottom: 0,
                                        left: 50,
                                        right: 50
                                    }
                                })
                            }
                        } else {
                            this.noParent = true
                        }
                    })
                },
                /**
                 * 增加空的数据源
                 * @param map 地图
                 * @param sourceId 数据源ID
                 */
                addEmptySource(map, sourceId) {
                    if (!map.getSource(sourceId)) {
                        map.addSource(sourceId, {
                            "type": "geojson",
                            "data": {
                                type: "FeatureCollection",
                                features: []
                            }
                        })
                    }
                },
                /**
                 * 增加文本图层
                 * @param map 地图
                 * @param layerId   图层ID
                 * @param sourceId  数据源ID
                 * @param textColor 文本颜色
                 */
                addTextLayer(map, layerId, sourceId, textColor) {
                    map.addLayer({
                        id: layerId + "-symbol",
                        type: 'symbol',
                        minzoom: 16,
                        source: sourceId,
                        layout: {
                            'text-size': 16,
                            'text-field': ['get', 'name']
                        },
                        paint: {
                            'text-color': textColor
                        }
                    })
                },
                /**
                 * 增加线图层
                 * @param map 地图
                 * @param layerId     图层ID
                 * @param sourceId    数据源ID
                 * @param lineColor   线颜色
                 */
                addLineLayer(map, layerId, sourceId, lineColor) {
                    map.addLayer({
                        'id': layerId + "-line",
                        'type': 'line',
                        'source': sourceId,
                        'minzoom': 12,
                        'paint': {
                            'line-color': lineColor,
                            'line-width': [
                                'match',
                                ['get', 'type'],
                                'parent',
                                4,
                                2
                            ]
                        }
                    })
                },
                // 点图层
                addPointLayer(map, id, maxZoom, textColor, overlap) {
                    map.loadImage('lib/mapbox/img/bus-points-address.png', (error, image) => {
                        if (error) throw error;
                        const img = id + '-img';
                        map.addImage(img, image);
                        map.addLayer({
                            id: id,
                            source: id,
                            type: 'symbol',
                            minzoom: 11,
                            layout: {
                                'icon-image': ["step", ["zoom"], img, maxZoom, ''],
                                "icon-size": ["interpolate", ["linear"],
                                    ["zoom"], 12, 0.4, 18, 1.2
                                ],
                                'text-size': ["interpolate", ["linear"],
                                    ["zoom"], 12, 10, 18, 20
                                ],
                                'text-field': ['get', 'name'],
                                'text-justify': 'center',
                                'text-offset': ["interpolate", ["linear"],
                                    ["zoom"], 12, ['literal', [0, 0.9]], 18, ['literal', [0, 1.2]]
                                ],
                                'text-anchor': 'top',
                                'text-letter-spacing': 0.2,
                                'text-max-width': 12,
                                'icon-allow-overlap': overlap,
                                'icon-ignore-placement': overlap,
                                'icon-optional': overlap,
                                'text-allow-overlap': overlap,
                                'text-ignore-placement': overlap
                            },
                            paint: {
                                'text-color': textColor,
                                'text-halo-blur': ["interpolate", ["linear"],
                                    ["zoom"], 12, 0.04, 18, 0.12
                                ],
                                'text-halo-color': '#2C3035',
                                'text-halo-width': ["interpolate", ["linear"],
                                    ["zoom"], 12, 0.2, 18, 0.6
                                ]
                            }
                        })
                    })
                }
            }
        }
    }

    module.exports = {
        onload
    };
});
